package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ArticleFreemarkerService;
import com.heima.common.constants.ArticleConstants;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.search.vos.SearchArticleVo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
@Transactional
public class ArticleFreemarkerServiceImpl implements ArticleFreemarkerService {
    @Autowired
    private Configuration configuration;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 生成静态模板文件存储到minIO
     * @param apArticle
     * @param content
     */
    @Override
    @Async //异步调用
    public void buildArticleToMinIO(ApArticle apArticle, String content) {
        try {
            //1、获取文章内容（非空校验）
            if (StringUtils.isNotBlank(content)) {
                //2、基于freemarker生成html文件
                //2.1、获取模板
                Template template = configuration.getTemplate("article.ftl");
                //2.2、输出流
                StringWriter sw = new StringWriter();
                //2.3、准备参数，文章内容转为json数组
                Map<String, Object> map = new HashMap<>();
                map.put("content", JSON.parseArray(content));
                //2.4、合并模板以及文件
                template.process(map, sw);
                //3、存入minIO
                //3.1、从输入流中获取数组
                ByteArrayInputStream bais = new ByteArrayInputStream(sw.toString().getBytes());
                //3.2、存入minIO
                String path = fileStorageService.uploadHtmlFile("", apArticle.getId() + ".html", bais);
                //4、保存static_url到文章表
                apArticleMapper.update(null, Wrappers.<ApArticle>lambdaUpdate()
                        .eq(ApArticle::getId, apArticle.getId())
                        .set(ApArticle::getStaticUrl, path));
                //5、发送消息给kafka，创建索引
                //5.1、创建消息载体对象
                SearchArticleVo searchArticleVo = new SearchArticleVo();
                //5.2、拷贝属性
                BeanUtils.copyProperties(apArticle,searchArticleVo);
                //5.3、content url 需要另外设置
                searchArticleVo.setContent(content);
                searchArticleVo.setStaticUrl(path);
                //5.4、往kafka发送消息
                kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC,JSON.toJSONString(searchArticleVo));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
